﻿#include "precomp.h"
#include "jsqldatamgr.h"
#include "jsqltablemgr.h"
#include <QSqlQuery>
#include "jprecitimer.h"
#include "sqlite/sqlite3.h"
#include "jtableview.h"

// - class JSqlDataMgrPrivate -

class JSqlDataMgrPrivate
{
    J_DECLARE_PUBLIC(JSqlDataMgr)
    public:
        JSqlDataMgrPrivate(JSqlDataMgr *parent) :
      q_ptr(parent),
        tableMgr(0)
    {

    }

private:
    JSqlTableMgr *tableMgr;
    QSqlDatabase db;
    QSqlQuery query;
};

// - class JSqlDataMgr -

J_IMPLEMENT_SINGLE_INSTANCE(JSqlDataMgr)

bool JSqlDataMgr::transaction()
{
    Q_D(JSqlDataMgr);
    return d->db.transaction();
}

bool JSqlDataMgr::commit()
{
    Q_D(JSqlDataMgr);
    bool result = d->db.commit();
    d->query.clear();
    return result;
}

bool JSqlDataMgr::rollback()
{
    Q_D(JSqlDataMgr);
    bool result = d->db.rollback();
    d->query.clear();
    return result;
}

bool JSqlDataMgr::executeSql(const QString &query)
{
    Q_D(JSqlDataMgr);
    bool result = d->query.exec(query);
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(d->query.lastError().text());
        return false;
    }

    return true;
}

bool JSqlDataMgr::existsTable(const QString &tableName) const
{
    Q_D(const JSqlDataMgr);
    return d->tableMgr->existsTable(tableName);
}

bool JSqlDataMgr::createSignalTable(const QString &tableName)
{
    Q_D(JSqlDataMgr);
    return d->tableMgr->createSignalTable(tableName);
}

bool JSqlDataMgr::createRecordTable(const QString &tableName, const QStringList &varNames)
{
    Q_D(JSqlDataMgr);
    return d->tableMgr->createRecordTable(tableName, varNames);
}

bool JSqlDataMgr::createHotSpotTable(const QString &tableName)
{
    Q_D(JSqlDataMgr);
    return d->tableMgr->createHotSpotTable(tableName);
}

bool JSqlDataMgr::addMainTableData(const stMainTableInfo &data)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("insert into %1(JX,JH,RQ,JC,DYXHB,DYZB,DYRDFW)"
                                     " values('%2','%3','%4',%5,'%6','%7','%8')")
                             .arg(d->tableMgr->mainTableName())
                             .arg(data.JX)
                             .arg(data.JH)
                             .arg(data.RQ.toString("yyyy/MM/dd"))
                             .arg(data.JC)
                             .arg(data.DYXHB)
                             .arg(data.DYZB)
                             .arg(data.DYRDFW));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    return true;
}

bool JSqlDataMgr::removeMainTableData(const JFileNameInfo &info)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("delete from %1"
                                     " where JX='%2' and JH='%3'and RQ='%4' and JC=%5")
                             .arg(d->tableMgr->mainTableName())
                             .arg(info.JX)
                             .arg(info.JH)
                             .arg(info.minRQ.toString("yyyy/MM/dd"))
                             .arg(info.JC));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    return true;
}

bool JSqlDataMgr::existsMainTable(const JFileNameInfo &info) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select DYXHB,DYZB from %1"
                                     " where JX='%2' and JH='%3'and RQ='%4' and JC=%5")
                             .arg(d->tableMgr->mainTableName())
                             .arg(info.JX)
                             .arg(info.JH)
                             .arg(info.minRQ.toString("yyyy/MM/dd"))
                             .arg(info.JC));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    if (query.next()) {
        if (query.value(0).toInt() > 0) {
            return true;
        }
    }

    return false;
}

bool JSqlDataMgr::readMainTable(const JFileNameInfo &info, QString &DYXHB, QString &DYZB)
{
    //
    DYXHB.clear();
    DYZB.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select DYXHB,DYZB from %1"
                                     " where JX='%2' and JH='%3'and RQ='%4' and JC=%5")
                             .arg(d->tableMgr->mainTableName())
                             .arg(info.JX)
                             .arg(info.JH)
                             .arg(info.minRQ.toString("yyyy/MM/dd"))
                             .arg(info.JC));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    if (!query.next()) {
        return false;
    }

    DYXHB = query.value(0).toString();
    DYZB = query.value(1).toString();

    return true;
}

bool JSqlDataMgr::addMainTableData(const QList<stMainTableInfo> &data)
{
    foreach (const stMainTableInfo &item, data) {
        if (!addMainTableData(item)) {
            return false;
        }
    }

    return true;
}

bool JSqlDataMgr::readMainTableBySection(const QString &sectionName,
                                         const QString &sectionValue,
                                         stMainTableInfo &info)
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select JX,JH,RQ,JC,DYXHB,DYZB,DYRDFW from %1 where %2='%3'")
                             .arg(d->tableMgr->mainTableName())
                             .arg(sectionName)
                             .arg(sectionValue));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (!query.next()) {
        return false;
    }

    info.JX = query.value(0).toString();
    info.JH = query.value(1).toString();
    info.RQ = query.value(2).toDate();
    info.JC = query.value(3).toInt();
    info.DYXHB = query.value(4).toString();
    info.DYZB = query.value(5).toString();
    info.DYRDFW = query.value(6).toString();

    return true;
}

bool JSqlDataMgr::addSignalData(const QString &tableName, const stSignalInfo &data,
                                bool isIgnoreSift, bool update)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select count(*) from %1 where YXHM='%2'")
                             .arg(tableName)
                             .arg(data.YXHM));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    //
    if (!query.next()) {
        return false;
    }

    //
    if (query.value(0).toInt() > 0) {
        // 已存在
        if (update) {
            result = query.exec(QString("update %1 set BM='%3',SSJX='%4',SSJH='%5',SSRQ='%6',SSJC=%7,SXBZ=%8"
                                        " where YXHM='%2'")
                                .arg(tableName)
                                .arg(data.YXHM)
                                .arg(data.BM)
                                .arg(data.SSJX)
                                .arg(data.SSJH)
                                .arg(data.SSRQ.toString("yyyy/MM/dd"))
                                .arg(data.SSJC)
                                .arg(data.SXBZ ? 1 : 0));
            if (!result) {
                qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
                return false;
            }
        }
    } else if (isIgnoreSift || data.SXBZ) {
        //
        result = query.exec(QString("insert into %1(YXHM,BM,SSJX,SSJH,SSRQ,SSJC,SXBZ,GJBZ,XZBZ)"
                                    " values('%2','%3','%4','%5','%6',%7, %8, %9, %10)")
                            .arg(tableName)
                            .arg(data.YXHM)
                            .arg(data.BM)
                            .arg(data.SSJX)
                            .arg(data.SSJH)
                            .arg(data.SSRQ.toString("yyyy/MM/dd"))
                            .arg(data.SSJC)
                            .arg(data.SXBZ ? 1 : 0)
                            .arg(data.GJBZ ? 1 : 0)
                            .arg(data.XZBZ ? 1 : 0));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }
    }

    return true;
}

bool JSqlDataMgr::addSignalData(const QString &tableName,
                                const QList<stSignalInfo> &data,
                                bool isIgnoreSift)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    if (!isIgnoreSift) {
        //JSqlTableMgr::instance()->clearTable(tableName);
    }

    //
    QSqlQuery queryInsert(d->db), queryUpdate(d->db), queryFind(d->db);
    bool result = false;

    //
    d->db.transaction();

    //
    result = queryInsert.prepare(QString("insert into %1(YXHM,BM,SSJX,SSJH,SSRQ,SSJC,SXBZ,GJBZ,XZBZ)"
                                         " values(?,?,?,?,?,?,?,?,?)").arg(tableName));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(queryInsert.lastError().text());
        return false;
    }
    //
    result = queryUpdate.prepare(QString("update %1 set BM=?,SSJX=?,SSJH=?,SSRQ=?,SSJC=?,SXBZ=?,GJBZ=?,XZBZ=?"
                                         " where YXHM=?")
                                 .arg(tableName));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(queryUpdate.lastError().text());
        return false;
    }
    //
    result = queryFind.prepare(QString("select count() from %1 where YXHM=?").arg(tableName));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(queryFind.lastError().text());
        return false;
    }
    //
    foreach (const stSignalInfo &item, data) {
        //
        if (isIgnoreSift || item.SXBZ) {
            //
            queryFind.addBindValue(item.YXHM);
            if (!queryFind.exec() || !queryFind.next()) {
                d->db.rollback();
                qCritical() << QStringLiteral("命令执行失败！[%1]").arg(queryFind.lastError().text());
                return false;   //error
            }
            //
            if (queryFind.value(0).toInt() > 0) {
                queryUpdate.addBindValue(item.BM);
                queryUpdate.addBindValue(item.SSJX);
                queryUpdate.addBindValue(item.SSJH);
                queryUpdate.addBindValue(item.SSRQ.toString("yyyy/MM/dd"));
                queryUpdate.addBindValue(item.SSJC);
                queryUpdate.addBindValue(item.SXBZ ? 1 : 0);
                queryUpdate.addBindValue(item.GJBZ ? 1 : 0);
                queryUpdate.addBindValue(item.XZBZ ? 1 : 0);
                queryUpdate.addBindValue(item.YXHM);
                //
                if (!queryUpdate.exec()) {
                    d->db.rollback();
                    qCritical() << QStringLiteral("命令执行失败！[%1]").arg(queryUpdate.lastError().text());
                    return false;
                }
            } else {
                queryInsert.addBindValue(item.YXHM);
                queryInsert.addBindValue(item.BM);
                queryInsert.addBindValue(item.SSJX);
                queryInsert.addBindValue(item.SSJH);
                queryInsert.addBindValue(item.SSRQ.toString("yyyy/MM/dd"));
                queryInsert.addBindValue(item.SSJC);
                queryInsert.addBindValue(item.SXBZ ? 1 : 0);
                queryInsert.addBindValue(item.GJBZ ? 1 : 0);
                queryInsert.addBindValue(item.XZBZ ? 1 : 0);
                //
                if (!queryInsert.exec()) {
                    d->db.rollback();
                    qCritical() << QStringLiteral("命令执行失败！[%1]").arg(queryInsert.lastError().text());
                    return false;
                }
            }
        }
    }

    //
    d->db.commit();

    return true;
}

bool JSqlDataMgr::readSignalData(const QString &tableName, QList<stSignalInfo> &data) const
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select * from %1 where SXBZ=1 order by oid").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        stSignalInfo info;
        info.YXHM = query.value(0).toString();
        info.BM = query.value(1).toString();
        info.SSJX = query.value(2).toString();
        info.SSJH = query.value(3).toString();
        info.SSRQ = query.value(4).toDate();
        info.SSJC = query.value(5).toInt();
        info.SXBZ = query.value(6).toBool();
        info.GJBZ = query.value(7).toBool();
        info.XZBZ = query.value(8).toBool();
        data.append(info);
    }

    return true;
}

bool JSqlDataMgr::readAllSignalData(const QString &tableName, QList<stSignalInfo> &data) const
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select * from %1 order by oid").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        stSignalInfo info;
        info.YXHM = query.value(0).toString();
        info.BM = query.value(1).toString();
        info.SSJX = query.value(2).toString();
        info.SSJH = query.value(3).toString();
        info.SSRQ = query.value(4).toDate();
        info.SSJC = query.value(5).toInt();
        info.SXBZ = query.value(6).toBool();
        info.GJBZ = query.value(7).toBool();
        info.XZBZ = query.value(8).toBool();
        data.append(info);
    }

    return true;
}

bool JSqlDataMgr::readSignalDataTime(const QString &tableName, stSignalInfo &data) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select YXHM,BM,SSJX,SSJH,SSRQ,SSJC"
                                     ",SXBZ,GJBZ,XZBZ from %1 where oid=1").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        data.YXHM = query.value(0).toString();
        data.BM = query.value(1).toString();
        data.SSJX = query.value(2).toString();
        data.SSJH = query.value(3).toString();
        data.SSRQ = query.value(4).toDate();
        data.SSJC = query.value(5).toInt();
        data.SXBZ = query.value(6).toBool();
        data.GJBZ = query.value(7).toBool();
        data.XZBZ = query.value(8).toBool();
    } else {
        return false;
    }

    return true;
}

bool JSqlDataMgr::readSignalData(const JFileNameInfo &info, QList<stSignalInfo> &data,
                                 bool hasTime) const
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    QStringList suffixes;
    if (!readSubTableSuffix(info, suffixes)) {
        return false;
    }

    //
    if (suffixes.isEmpty()) {
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = false;

    // 查询所有已筛选的YXHM字段数据
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        result = query.exec(QString("select YXHM,BM,SSJX,SSJH,SSRQ,SSJC,SXBZ,GJBZ,XZBZ from %1 where SXBZ=1 order by oid")
                            .arg(JSqlTableMgr::instance()->signalTableNamePrefix().append(citerSuffixes.next())));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }

        // 读取数据
        if (!hasTime) {
            query.next();   // 略过时间信号项
        }
        while (query.next()) {
            QString symbol = query.value(0).toString();
            if (data.contains(stSignalInfo(symbol))) {
                continue;
            }
            //
            stSignalInfo info;
            info.YXHM = symbol;
            info.BM = query.value(1).toString();
            info.SSJX = query.value(2).toString();
            info.SSJH = query.value(3).toString();
            info.SSRQ = query.value(4).toDate();
            info.SSJC = query.value(5).toInt();
            info.SXBZ = query.value(6).toBool();
            info.GJBZ = query.value(7).toBool();
            info.XZBZ = query.value(8).toBool();
            data.append(info);
        }
    }

    return true;
}

bool JSqlDataMgr::updateSignalSift(const QString &tableName, const QMap<QString, bool> &mapSignalSift)
{
    if (mapSignalSift.isEmpty()) {
        return true;
    }

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    QSqlQuery query(d->db);
    bool result = true;

    d->db.transaction();

    //
    result = query.prepare(QString("update %1 set SXBZ=? where YXHM=?").arg(tableName));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }
    //
    QMapIterator<QString, bool> citer(mapSignalSift);
    while (citer.hasNext()) {
        citer.next();
        //
        query.addBindValue(citer.value());
        query.addBindValue(citer.key());
        //
        if (!query.exec()) {
            continue;
        }
    }

    d->db.commit();

    return true;
}

bool JSqlDataMgr::addRecordData(const QString &tableName, const QString &valuesString)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 获取对应的信号名
    QString DYXHB = JSqlTableMgr::signalTableNamePrefix().append(JSqlTableMgr::suffixOfSubTable(tableName));

    // 获取对应信号表的所有信号名称(按顺序)
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QStringLiteral("SELECT YXHM FROM %1 WHERE SXBZ=1 order by oid").arg(DYXHB));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 获取并序列化列表名
    QString columnsString;
    while (query.next()) {
        columnsString.append(query.value(0).toString() % ',');
    }
    columnsString.chop(1);  // 去掉最后一个','(如果有)

    // 存入数据库值表
    result = query.exec(QString("insert into %1(%2) values(%4)")
                        .arg(tableName)
                        .arg(columnsString)
                        .arg(valuesString));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    return true;
}

bool JSqlDataMgr::addRecordData(const QString &tableName, const QTime &time, const QList<double> &values)
{
    // 字符串化数值
    QString valuesString;
    valuesString.append("'" % time.toString("hh:mm:ss:zzz") % "',");
    foreach (const double &value, values) {
        valuesString.append(QString::number(value) % ',');
    }
    valuesString.chop(1);   // 去掉最后一个','(如果有)

    return addRecordData(tableName, valuesString);
}

bool JSqlDataMgr::addRecordData(const QString &tableName, const QString &columnsString, const QString &valuesString)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 存入数据库值表
    QSqlQuery query(d->db);
    bool result = query.exec(QString("insert into %1(%2) values(%4)")
                             .arg(tableName)
                             .arg(columnsString)
                             .arg(valuesString));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    return true;
}

bool JSqlDataMgr::addRecordData(const QString &tableName, const QString &columnsString,
                                const QTime &time, const QList<double> &values)
{
    // 字符串化数值
    QString valuesString;
    valuesString.append("'" % time.toString("hh:mm:ss:zzz") % "',");
    foreach (const double &value, values) {
        valuesString.append(QString::number(value) % ',');
    }
    valuesString.chop(1);   // 去掉最后一个','(如果有)

    return addRecordData(tableName, columnsString, valuesString);
}

bool JSqlDataMgr::addRecordData(const QString &tableName, const QStringList &sigs,
                                const QString &valuesString)
{
    return addRecordData(tableName, sigs.join(','), valuesString);
}

bool JSqlDataMgr::addRecordData(const QString &tableName, const QStringList &sigs,
                                const QTime &time, const QList<double> &values)
{
    return addRecordData(tableName, sigs.join(','), time, values);
}

bool JSqlDataMgr::addHotSpotData(const QString &tableName, const QRectF &range)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 存入数据库值表
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("insert into %1(XMIN,XMAX,YMIN,YMAX) values(%2,%3,%4,%5)")
                             .arg(tableName)
                             .arg(range.left(), 0, 'f')
                             .arg(range.right(), 0, 'f')
                             .arg(range.top(), 0, 'f')
                             .arg(range.bottom(), 0, 'f'));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    return true;
}

QStringList JSqlDataMgr::signalColumnNames(const QString &tableName, bool sift) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = true;

    //
    if (sift) {
        result = query.exec(QString("SELECT YXHM FROM %1 WHERE SXBZ=1 ORDER BY oid")
                            .arg(tableName));
    } else {
        result = query.exec(QString("SELECT YXHM FROM %1 ORDER BY oid")
                            .arg(tableName));
    }
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    QStringList columnNames;
    while (query.next()) {
        columnNames.append(query.value(0).toString());
    }

    return columnNames;
}

QStringList JSqlDataMgr::readSignalData(const JFileNameInfo &info, bool sift) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    //
    QStringList suffixes;
    if (!readSubTableSuffix(info, suffixes)) {
        return QStringList();
    }

    //
    if (suffixes.isEmpty()) {
        return QStringList();
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = false;

    QString sQuery;
    if (sift) {
        sQuery = QString("select YXHM from %1 WHERE SXBZ=1 order by oid");
    } else {
        sQuery = QString("select YXHM from %1 order by oid");
    }

    // 查询所有YXHM字段数据
    QStringList columnNames;
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        result = query.exec(sQuery.arg(JSqlTableMgr::instance()->signalTableNamePrefix()
                                       .append(citerSuffixes.next())));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            continue;
        }
        //
        while (query.next()) {
            QString symbol = query.value(0).toString();
            if (!columnNames.contains(symbol)) {
                columnNames.append(symbol);
            }
        }
    }

    return columnNames;
}

QString JSqlDataMgr::mainTableName()
{
    return JSqlTableMgr::mainTableName();
}

QString JSqlDataMgr::signalTableNamePrefix()
{
    return JSqlTableMgr::signalTableNamePrefix();
}

QString JSqlDataMgr::recordTableNamePrefix()
{
    return JSqlTableMgr::recordTableNamePrefix();
}

QString JSqlDataMgr::hotSpotTableNamePrefix()
{
    return JSqlTableMgr::hotSpotTableNamePrefix();
}

QStringList JSqlDataMgr::readAllJX() const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询所有JX字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct JX from %1 order by 1")
                             .arg(d->tableMgr->mainTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    while (query.next()) {
        l << query.value(0).toString();
    }

    return l;
}

QStringList JSqlDataMgr::readAllJH() const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct JH from %1 order by 1")
                             .arg(d->tableMgr->mainTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    while (query.next()) {
        l << query.value(0).toString();
    }

    return l;
}

QList<QDate> JSqlDataMgr::readAllRQ() const
{

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QList<QDate>();
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct RQ from %1 order by 1")
                             .arg(d->tableMgr->mainTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QList<QDate>();
    }

    // 读取数据
    QList<QDate> l;
    while (query.next()) {
        l << query.value(0).toDate();
    }

    return l;
}

QList<int> JSqlDataMgr::readAllJC() const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QList<int>();
    }

    // 查询所有JC字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct JC from %1 order by 1")
                             .arg(d->tableMgr->mainTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QList<int>();
    }

    // 读取数据
    QList<int> l;
    while (query.next()) {
        l << query.value(0).toInt();
    }

    return l;
}

QStringList JSqlDataMgr::readAllJCAsString() const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询所有JC字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct JC from %1 order by 1")
                             .arg(d->tableMgr->mainTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    while (query.next()) {
        l << query.value(0).toString();
    }

    return l;
}

QList<int> JSqlDataMgr::readAllJC(const QString &JX, const QString &JH, const QDate &RQ) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QList<int>();
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct JC from %1 where JX='%2' and JH='%3' and RQ='%4'"
                                     " order by 1")
                             .arg(d->tableMgr->mainTableName())
                             .arg(JX).arg(JH).arg(RQ.toString("yyyy/MM/dd")));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QList<int>();
    }

    // 读取数据
    QList<int> l;
    while (query.next()) {
        l << query.value(0).toInt();
    }

    return l;
}

QStringList JSqlDataMgr::readAllJCAsString(const QString &JX, const QString &JH, const QDate &RQ) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select distinct JC from %1 where JX='%2' and JH='%3' and RQ='%4' order by 1")
                             .arg(d->tableMgr->mainTableName())
                             .arg(JX).arg(JH).arg(RQ.toString("yyyy/MM/dd")));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    while (query.next()) {
        l << query.value(0).toString();
    }

    return l;
}

QStringList JSqlDataMgr::readAllSignalTableName() const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select DYXHB from %1 order by oid")
                             .arg(d->tableMgr->mainTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    while (query.next()) {
        l << query.value(0).toString();
    }

    return l;
}

bool JSqlDataMgr::readSubTableSuffix(const QString &JX,
                                     const QString &JH,
                                     const QString &RQ,
                                     int JC,
                                     QStringList &suffixes) const
{
    //
    suffixes.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 生成查询语句
    QStringList l;
    if (!JX.isEmpty()) {
        l.append("JX='" % JX % "'");
    }
    if (!JH.isEmpty()) {
        l.append("JH='" % JH % "'");
    }
    if (!RQ.isEmpty()) {
        l.append("RQ='" % RQ % "'");
    }
    if (JC >= 0) {
        l.append("JC='" % QString::number(JC) % "'");
    }

    QString condition;
    if (!l.isEmpty()) {
        condition.append("where ");
        condition.append(l.join(" and "));
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select DYXHB from %1 %2 order by 1")
                             .arg(d->tableMgr->mainTableName())
                             .arg(condition));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        suffixes << query.value(0).toString().section('_', 2);
    }

    return true;
}

bool JSqlDataMgr::readSubTableSuffix(const JFileNameInfo &fileNameInfo,
                                     QStringList &suffixes) const
{
    //
    suffixes.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 生成查询语句
    QStringList l;
    if (!fileNameInfo.JX.isEmpty()) {
        l.append("JX='" % fileNameInfo.JX % "'");
    }
    if (!fileNameInfo.JH.isEmpty()) {
        l.append("JH='" % fileNameInfo.JH % "'");
    }
    if (fileNameInfo.maxRQ.isNull()) {
        if (fileNameInfo.minRQ.isValid()) {
            l.append("RQ='" % fileNameInfo.minRQ.toString("yyyy/MM/dd") % "'");
        }
    } else if (fileNameInfo.minRQ.isValid()) {
        l.append("RQ between '" % fileNameInfo.minRQ.toString("yyyy/MM/dd") % "' and '"
                 % fileNameInfo.maxRQ.toString("yyyy/MM/dd") % "'");
    }
    if (fileNameInfo.JC >= 0) {
        l.append("JC='" % QString::number(fileNameInfo.JC) % "'");
    }

    QString condition;
    if (!l.isEmpty()) {
        condition.append("where ");
        condition.append(l.join(" and "));
    }

    // 查询所有JH字段数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select DYXHB from %1 %2 order by 1")
                             .arg(d->tableMgr->mainTableName())
                             .arg(condition));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        suffixes << query.value(0).toString().section('_', 2);
    }

    return true;
}

QStringList JSqlDataMgr::readSignalTableColumnName(const QString &tableName, bool sift) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = true;
    if (sift) {
        result = query.exec(QString("select YXHM,BM from %1 WHERE SXBZ=1 ORDER BY oid")
                            .arg(tableName));
    } else {
        result = query.exec(QString("select YXHM,BM from %1 ORDER BY oid")
                            .arg(tableName));
    }
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    QString sTemp;
    while (query.next()) {
        sTemp = query.value(1).toString();
        if (sTemp.isEmpty()) {
            l.append(query.value(0).toString());    // 别名不存在，用原信号名替代别名
        } else {
            l.append(sTemp);
        }
    }

    return l;
}

QStringList JSqlDataMgr::readSignalTableColumnSymbol(const QString &tableName, bool sift) const
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return QStringList();
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = true;
    if (sift) {
        result = query.exec(QString("select YXHM from %1 WHERE SXBZ=1 ORDER BY oid")
                            .arg(tableName));
    } else {
        result = query.exec(QString("select YXHM from %1 ORDER BY oid")
                            .arg(tableName));
    }
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return QStringList();
    }

    // 读取数据
    QStringList l;
    while (query.next()) {
        l.append(query.value(0).toString());
    }

    return l;
}

bool JSqlDataMgr::readRecordData(const QString &tableName, QVector<QVector<QVariant> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select * from %1 order by 1")
                             .arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    int i = 0;
    while (query.next()) {
        QSqlRecord record = query.record();
        QVector<QVariant> rowVars;
        for (i = 0; i < record.count(); ++i) {
            rowVars.append(record.value(i));
        }
        data.append(rowVars);
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 QList<QVariantList > &data,
                                 const QStringList &symbols,
                                 int rowOffset, int rowCount,
                                 const QString &orderSection)
{
    //
    data.clear();

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //JPreciTimer ptimer;
    //ptimer.reset();

    //
    QString sSymbols;
    if (symbols.count() == 1) {
        sSymbols = symbols.first();
    } else {
        sSymbols = symbols.join(",");
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %4 from %1 order by %5 limit %2,%3")
                             .arg(tableName)
                             .arg(rowOffset)
                             .arg(rowCount)
                             .arg(sSymbols)
                             .arg(orderSection));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    int i = 0;
    while (query.next()) {
        QSqlRecord record = query.record();
        QVariantList rowVars;
        for (i = 0; i < record.count(); ++i) {
            rowVars.append(record.value(i));
        }
        data.append(rowVars);
    }

    //qDebug() << ptimer.ustick();

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QStringList sectionNames,
                                 QVector<QVector<QVariant> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2 from %1")
                             .arg(tableName).arg(sectionNames.join(',')));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    int i = 0;
    while (query.next()) {
        QSqlRecord record = query.record();
        QVector<QVariant> rowVars;
        for (i = 0; i < record.count(); ++i) {
            rowVars.append(record.value(i));
        }
        data.append(rowVars);
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName, const QString &section1,
                                 const QString &section2, QVector<QPointF> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%3 from %1")
                             .arg(tableName).arg(section1).arg(section2));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        data.append(QPointF(query.value(0).toDouble(), query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QString &section1,
                                 const QString &section2,
                                 const QRectF &range,
                                 QVector<QPointF> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%3 from %1 where %2 between %4 and %5"
                                     " and %3 between %6 and %7")
                             .arg(tableName).arg(section1).arg(section2)
                             .arg(range.left()).arg(range.right())
                             .arg(range.top()).arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        data.append(QPointF(query.value(0).toDouble(), query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QString &section1,
                                 const QString &section2,
                                 const QString &sectionTime,
                                 const QString &sectionValue,
                                 const QRectF &range,
                                 QVector<QPointF> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %8,%9 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7) order by %2")
                             .arg(tableName).arg(sectionTime).arg(sectionValue)
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                             .arg(range.top()).arg(range.bottom())
                             .arg(section1).arg(section2));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        data.append(QPointF(query.value(0).toDouble(), query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QString &tableName,
                                  const QString &section1,
                                  const QString &section2,
                                  const QString &sectionX,
                                  const QString &sectionValue,
                                  const QRectF &range,
                                  QVector<QPointF> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %8,%9 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7)")
                             .arg(tableName).arg(sectionX).arg(sectionValue)
                             .arg(range.left()).arg(range.right())
                             .arg(range.top()).arg(range.bottom())
                             .arg(section1).arg(section2));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        data.append(QPointF(query.value(0).toDouble(), query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName, const QString &sectionTime,
                                 const QString &sectionValue, QList<QPair<QTime, qreal> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%3 from %1 order by %2")
                             .arg(tableName).arg(sectionTime).arg(sectionValue));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        QTime time = QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz");
        data.append(QPair<QTime, qreal>(time, query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName, const QString &section1,
                                 const QString &section2, const QRectF &range,
                                 QList<QPointF> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%3 from %1 where %2 between %4 and %5"
                                     " and %3 between %6 and %7")
                             .arg(tableName).arg(section1).arg(section2)
                             .arg(range.left()).arg(range.right())
                             .arg(range.top()).arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        data.append(QPointF(query.value(0).toDouble(), query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName, const QString &sectionTime,
                                 const QString &sectionValue, const QRectF &range,
                                 QList<QPair<QTime, qreal> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%3 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7) order by %2")
                             .arg(tableName).arg(sectionTime).arg(sectionValue)
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                             .arg(range.top()).arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        QTime time = QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz");
        data.append(QPair<QTime, qreal>(time, query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QString &section1,
                                 const QString &sectionTime,
                                 const QString &sectionValue,
                                 const QRectF &range,
                                 QList<QPair<QTime, qreal> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%8 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7) order by %2")
                             .arg(tableName).arg(sectionTime).arg(sectionValue)
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                             .arg(range.top()).arg(range.bottom())
                             .arg(section1));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        QTime time = QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz");
        data.append(QPair<QTime, qreal>(time, query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QString &tableName,
                                  const QString &section1,
                                  const QString &sectionX,
                                  const QString &sectionValue,
                                  const QRectF &range,
                                  QList<QPair<QTime, qreal> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2,%8 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7)")
                             .arg(tableName).arg(sectionX).arg(sectionValue)
                             .arg(range.left())
                             .arg(range.right())
                             .arg(range.top())
                             .arg(range.bottom())
                             .arg(section1));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        QTime time = QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz");
        data.append(QPair<QTime, qreal>(time, query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QString &tableName, const QString &sectionX, const QString &sectionY, const QString &rangeSectionX, const QString &rangeSectionY, const QRectF &range, QList<QPair<QTime, qreal> > &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %8,%9 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7)")
                             .arg(tableName).arg(rangeSectionX).arg(rangeSectionY)
                             .arg(range.left())
                             .arg(range.right())
                             .arg(range.top())
                             .arg(range.bottom())
                             .arg(sectionX)
                             .arg(sectionY));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        QTime time = QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz");
        data.append(QPair<QTime, qreal>(time, query.value(1).toDouble()));
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QString &sectionTime,
                                 const QString &sectionValue,
                                 const QRectF &range,
                                 QList<QVariantList> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select * from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7) order by %2")
                             .arg(tableName).arg(sectionTime).arg(sectionValue)
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                             .arg(range.top()).arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        QSqlRecord record = query.record();
        int count = record.count();
        if (count <= 0) {
            continue;
        }
        QVariantList rowVars;
        for (int i = 1; i < count; ++i) {   // 不读取第一个字段（XH）
            rowVars.append(record.value(i));
        }
        data.append(rowVars);
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QString &tableName,
                                  const QString &sectionX,
                                  const QString &sectionValue,
                                  const QRectF &range,
                                  QList<QVariantList> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select * from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7)")
                             .arg(tableName).arg(sectionX).arg(sectionValue)
                             .arg(range.left())
                             .arg(range.right())
                             .arg(range.top())
                             .arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    int i = 0;
    while (query.next()) {
        QSqlRecord record = query.record();
        QVariantList rowVars;
        for (i = 0; i < record.count(); ++i) {
            rowVars.append(record.value(i));
        }
        data.append(rowVars);
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QString &tableName,
                                  const QString &sectionX,
                                  const QString &sectionValue,
                                  const QRectF &range,
                                  const QStringList &symbols,
                                  QList<QVariant> &data,
                                  int rowOffset, int rowCount,
                                  const QString &orderSection)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    QString sSymbols;
    if (symbols.count() == 1) {
        sSymbols = symbols.first();
    } else {
        sSymbols = symbols.join(",");
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %8 from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7) order by %11 limit %9,%10")
                             .arg(tableName).arg(sectionX).arg(sectionValue)
                             .arg(range.left())
                             .arg(range.right())
                             .arg(range.top())
                             .arg(range.bottom())
                             .arg(sSymbols)
                             .arg(rowOffset)
                             .arg(rowCount)
                             .arg(orderSection));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    int i = 0;
    while (query.next()) {
        QSqlRecord record = query.record();
        QVariantList rowVars;
        for (i = 0; i < record.count(); ++i) {
            rowVars.append(record.value(i));
        }
        data.append(QVariant(rowVars));
    }

    return true;
}

int JSqlDataMgr::rowCountOfRecordDataV(const QString &tableName,
                                       const QString &sectionX,
                                       const QString &sectionValue,
                                       const QRectF &range)
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return 0;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select count(*) from %1 where"
                                     " (%2 between '%4' and '%5')"
                                     " and (%3 between %6 and %7)")
                             .arg(tableName).arg(sectionX).arg(sectionValue)
                             .arg(range.left())
                             .arg(range.right())
                             .arg(range.top())
                             .arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return 0;
    }

    if (query.next()) {
        return query.value(0).toInt();
    }

    return 0;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QStringList &sections,
                                 const QString &sectionTime,
                                 const QString &sectionValue,
                                 const QRectF &range,
                                 QList<QVariantList> &data)
{
    //
    data.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select %2 from %1 where"
                                     " (%3 between '%5' and '%6')"
                                     " and (%4 between %7 and %8) order by %3")
                             .arg(tableName).arg(sections.join(','))
                             .arg(sectionTime).arg(sectionValue)
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                             .arg(range.top()).arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    int i = 0;
    while (query.next()) {
        QVariantList rowVars;
        for (i = 0; i < query.size(); ++i) {
            rowVars.append(query.value(i));
        }
        data.append(rowVars);
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QString &sectionTime,
                                 const QString &sectionValue,
                                 const QString &section1,
                                 const QRectF &range,
                                 QRectF &range1)
{
    // 初始化
    range1 = QRectF();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select min(%4),max(%4) from %1 where"
                                     " (%2 between '%5' and '%6')"
                                     " and (%3 between %7 and %8) order by %2")
                             .arg(tableName)
                             .arg(sectionTime).arg(sectionValue)
                             .arg(section1)
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                             .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                             .arg(range.top()).arg(range.bottom()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        range1.setLeft(range.left());
        range1.setRight(range.right());
        range1.setTop(query.value(0).toDouble());
        range1.setBottom(query.value(1).toDouble());
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const JFileNameInfo &fileNameInfo,
                                 const QString &sectionTime,
                                 const QString &sectionValue,
                                 const QString &section1,
                                 const QRectF &range,
                                 QRectF &range1)
{
    // 初始化
    range1 = QRectF();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    QStringList suffixes;
    bool result = readSubTableSuffix(fileNameInfo, suffixes);
    if (!result || suffixes.isEmpty()) {
        qCritical() << QStringLiteral("获取数据记录表名称后缀失败！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    QList<QRectF> newRanges;
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        const QString &suffix = citerSuffixes.next();
        // 查询数据
        result = query.exec(QString("select min(%4),max(%4) from %1 where"
                                    " (%2 between '%5' and '%6')"
                                    " and (%3 between %7 and %8) order by %2")
                            .arg(JSqlTableMgr::recordTableNamePrefix().append(suffix))
                            .arg(sectionTime).arg(sectionValue)
                            .arg(section1)
                            .arg(QTime::fromMSecsSinceStartOfDay((int)range.left()).toString("hh:mm:ss:zzz"))
                            .arg(QTime::fromMSecsSinceStartOfDay((int)range.right()).toString("hh:mm:ss:zzz"))
                            .arg(range.top()).arg(range.bottom()));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }

        // 读取数据
        if (query.next()) {
            QRectF tempRect;
            tempRect.setLeft(range.left());
            tempRect.setRight(range.right());
            tempRect.setTop(query.value(0).toDouble());
            tempRect.setBottom(query.value(1).toDouble());
            newRanges.append(tempRect);
        }
    }

    // 检测有效性
    if (newRanges.isEmpty()) {
        //
        qWarning() << QStringLiteral("没有获取到有效范围值");
        return false;
    }

    // 合并区域，取交集
    range1 = newRanges.takeFirst();
    QListIterator<QRectF> citerNewRanges(newRanges);
    while (citerNewRanges.hasNext()) {
        const QRectF &newRange = citerNewRanges.next();
        range1 = range1.intersected(newRange);
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const JFileNameInfo &fileNameInfo,
                                  const QString &machSection,
                                  const QString &heightSection,
                                  const QString &sectionValue,
                                  const QRectF &rangeBase,
                                  QPointF &range)
{
    // 初始化
    range = QPointF();

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    d->db.transaction();

    //
    QStringList suffixes;
    bool result = readSubTableSuffix(fileNameInfo, suffixes);
    if (!result || suffixes.isEmpty()) {
        d->db.rollback();
        qCritical() << QStringLiteral("获取数据记录表名称后缀失败！");
        return false;
    }

    QString condition;
    condition.append(QString("(%1 between %3 and %4)"
                             " and "
                             "(%2 between %5 and %6)")
                     .arg(machSection)
                     .arg(heightSection)
                     .arg(rangeBase.left())
                     .arg(rangeBase.right())
                     .arg(rangeBase.top())
                     .arg(rangeBase.bottom()));

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    QList<QPointF> newRanges;
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        const QString tableName = JSqlTableMgr::recordTableNamePrefix().append(citerSuffixes.next());
        // 查询数据
        result = query.exec(QString("select min(%2),max(%2) from %1 where %3")
                            .arg(tableName).arg(sectionValue).arg(condition));
        if (!result) {
            d->db.rollback();
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }

        // 读取数据
        if (query.next()) {
            newRanges.append(QPointF(query.value(0).toDouble(), query.value(1).toDouble()));
        }
    }

    //
    d->db.commit();

    // 检测有效性
    if (newRanges.isEmpty()) {
        //
        qWarning() << QStringLiteral("没有获取到有效范围值");
        return false;
    }

    // 合并区域，取交集
    range = newRanges.takeFirst(); //
    QListIterator<QPointF> citerNewRanges(newRanges);
    while (citerNewRanges.hasNext()) {
        const QPointF &newRange = citerNewRanges.next();
        range.setX(qMax(range.x(), newRange.x()));
        range.setY(qMin(range.y(), newRange.y()));
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QString &tableName,
                                  const QString &machSection,
                                  const QString &heightSection,
                                  const QString &sectionValue,
                                  const QRectF &rangeBase,
                                  QPointF &range)
{
    // 初始化
    range = QPointF();

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QString condition;
    condition.append(QString("(%1 between %3 and %4)"
                             " and "
                             "(%2 between %5 and %6)")
                     .arg(machSection)
                     .arg(heightSection)
                     .arg(rangeBase.left())
                     .arg(rangeBase.right())
                     .arg(rangeBase.top())
                     .arg(rangeBase.bottom()));

    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    // 查询数据
    bool result = query.exec(QString("select min(%2),max(%2) from %1 where %3")
                             .arg(tableName).arg(sectionValue).arg(condition));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据，取交集
    if (query.next()) {
        range = QPointF(query.value(0).toDouble(), query.value(1).toDouble());
    }

    return true;
}

bool JSqlDataMgr::readRecordData(const QString &tableName,
                                 const QString &sectionBase,
                                 const QString &sectionTime,
                                 const QList<QPair<QString, QRectF> > &ranges,
                                 QRectF &rangeBase)
{
    if (ranges.isEmpty()) {
        return false;
    }

    // 初始化
    rangeBase = QRectF();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QStringList conditions;
    QListIterator<QPair<QString, QRectF> > citerRanges(ranges);
    while (citerRanges.hasNext()) {
        const QPair<QString, QRectF> &range = citerRanges.next();
        conditions.append(QString("(%1 between '%3' and '%4') and (%2 between %5 and %6)")
                          .arg(sectionTime).arg(range.first)
                          .arg(QTime::fromMSecsSinceStartOfDay(range.second.left()).toString("hh:mm:ss:zzz"))
                          .arg(QTime::fromMSecsSinceStartOfDay(range.second.right()).toString("hh:mm:ss:zzz"))
                          .arg(range.second.top())
                          .arg(range.second.bottom()));
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("select min(%2),max(%2),min(%3),max(%3) from %1 where %4 order by %1")
                             .arg(tableName)
                             .arg(sectionTime).arg(sectionBase)
                             .arg(conditions.join(" and ")));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        rangeBase.setLeft(QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz").msecsSinceStartOfDay());
        rangeBase.setRight(QTime::fromString(query.value(1).toString(), "hh:mm:ss:zzz").msecsSinceStartOfDay());
        rangeBase.setTop(query.value(2).toDouble());
        rangeBase.setBottom(query.value(3).toDouble());
    }

    //
#if 0
    if (ranges.count() == 1 && sectionBase == ranges.first().first) {
        rangeBase = rangeBase.united(ranges.first().second);
    }
#endif
    return true;
}

bool JSqlDataMgr::readRecordData(const JFileNameInfo &fileNameInfo,
                                 const QString &sectionBase,
                                 const QString &sectionTime,
                                 const QList<QPair<QString, QRectF> > &ranges,
                                 QRectF &rangeBase)
{
    if (ranges.isEmpty()) {
        return false;
    }

    // 初始化
    rangeBase = QRectF();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QStringList conditions;
    QListIterator<QPair<QString, QRectF> > citerRanges(ranges);
    while (citerRanges.hasNext()) {
        const QPair<QString, QRectF> &range = citerRanges.next();
        conditions.append(QString("(%1 between '%3' and '%4') and (%2 between %5 and %6)")
                          .arg(sectionTime).arg(range.first)
                          .arg(QTime::fromMSecsSinceStartOfDay(range.second.left()).toString("hh:mm:ss:zzz"))
                          .arg(QTime::fromMSecsSinceStartOfDay(range.second.right()).toString("hh:mm:ss:zzz"))
                          .arg(range.second.top())
                          .arg(range.second.bottom()));
    }

    //
    QStringList suffixes;
    bool result = readSubTableSuffix(fileNameInfo, suffixes);
    if (!result || suffixes.isEmpty()) {
        qCritical() << QStringLiteral("获取数据记录表名称后缀失败！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    QList<QRectF> newRanges;
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        const QString &suffix = citerSuffixes.next();
        // 查询数据
        QSqlQuery query(d->db);
        bool result = query.exec(QString("select min(%2),max(%2),min(%3),max(%3) from %1 where %4 order by %2")
                                 .arg(JSqlTableMgr::recordTableNamePrefix().append(suffix))
                                 .arg(sectionTime).arg(sectionBase)
                                 .arg(conditions.join(" and ")));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }

        // 读取数据
        if (query.next()) {
            QRectF tempRect;
            tempRect.setLeft(QTime::fromString(query.value(0).toString(), "hh:mm:ss:zzz").msecsSinceStartOfDay());
            tempRect.setRight(QTime::fromString(query.value(1).toString(), "hh:mm:ss:zzz").msecsSinceStartOfDay());
            tempRect.setTop(query.value(2).toDouble());
            tempRect.setBottom(query.value(3).toDouble());
            newRanges.append(tempRect);
        }
    }

    // 检测有效性
    if (newRanges.isEmpty()) {
        //
        qWarning() << QStringLiteral("没有获取到有效范围值");
        return false;
    }

    // 合并区域，取交集
    rangeBase = newRanges.takeFirst(); //
    QListIterator<QRectF> citerNewRanges(newRanges);
    while (citerNewRanges.hasNext()) {
        const QRectF &newRange = citerNewRanges.next();
        rangeBase = rangeBase.intersected(newRange);
    }

    //
#if 0
    if (ranges.count() == 1 && sectionBase == ranges.first().first) {
        rangeBase = rangeBase.united(ranges.first().second);
    }
#endif
    return true;
}

bool JSqlDataMgr::readRecordDataV(const JFileNameInfo &fileNameInfo,
                                  const QString &machSection,
                                  const QString &heightSection,
                                  const QMap<QString, QPointF> &mapRanges,
                                  QRectF &range)
{
    if (mapRanges.isEmpty()) {
        return false;
    }

    // 初始化
    range = QRectF();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QStringList conditions;
    QMapIterator<QString, QPointF> citerRanges(mapRanges);
    while (citerRanges.hasNext()) {
        citerRanges.next();
        conditions.append(QString("(%1 between '%2' and '%3')")
                          .arg(citerRanges.key())
                          .arg(citerRanges.value().x())
                          .arg(citerRanges.value().y()));
    }
    QString sCondition = conditions.join(" and ");
    conditions.clear();

    //
    QStringList suffixes;
    bool result = readSubTableSuffix(fileNameInfo, suffixes);
    if (!result || suffixes.isEmpty()) {
        qCritical() << QStringLiteral("获取数据记录表名称后缀失败！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    QList<QRectF> newRanges;
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        const QString tableName = JSqlTableMgr::recordTableNamePrefix().append(citerSuffixes.next());
        //
        result = query.exec(QString("select min(%2),max(%2),min(%3),max(%3) from %1 where %4")
                            .arg(tableName)
                            .arg(machSection).arg(heightSection)
                            .arg(sCondition));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }

        // 读取数据
        if (query.next()) {
            QRectF tempRect;
            tempRect.setLeft(query.value(0).toDouble());
            tempRect.setRight(query.value(1).toDouble());
            tempRect.setTop(query.value(2).toDouble());
            tempRect.setBottom(query.value(3).toDouble());
            newRanges.append(tempRect);
        }
    }

    // 检测有效性
    if (newRanges.isEmpty()) {
        //
        qWarning() << QStringLiteral("没有获取到有效范围值");
        return false;
    }

    // 合并区域，取交集
    range = newRanges.takeFirst(); //
    QListIterator<QRectF> citerNewRanges(newRanges);
    while (citerNewRanges.hasNext()) {
        const QRectF &newRange = citerNewRanges.next();
        range = range.intersected(newRange);
    }

    return true;
}

bool JSqlDataMgr::readRecordDataV(const QMap<QString, QMap<QString, QPointF> > &mapRanges,
                                  QRectF &range)
{
    if (mapRanges.isEmpty()) {
        return false;
    }

    // 初始化
    range = QRectF();

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = true;

    //
    d->db.transaction();

    //
    QList<QRectF> newRanges;

    //
    QMapIterator<QString, QMap<QString, QPointF> > citerMapRanges(mapRanges);
    while (citerMapRanges.hasNext()) {
        citerMapRanges.next();
        const QString &suffix =citerMapRanges.key();
        const QMap<QString, QPointF> &mapRange = citerMapRanges.value();
        // 获取M-H信号名称
        QString machSection, heightSection;
        if (!readSignalAxisSection(signalTableNamePrefix().append(suffix),
                                   QStringLiteral("马赫数"),
                                   QStringLiteral("高度"),
                                   machSection, heightSection)) {
            continue;
        }
        //
        QStringList conditions;
        QMapIterator<QString, QPointF> citerMapRange(mapRange);
        while (citerMapRange.hasNext()) {
            citerMapRange.next();
            conditions.append(QString("(%1 between '%2' and '%3')")
                              .arg(citerMapRange.key())
                              .arg(citerMapRange.value().x())
                              .arg(citerMapRange.value().y()));
        }
        const QString sCondition = conditions.join(" and ");
        conditions.clear();
        //
        result = query.exec(QString("select min(%2),max(%2),min(%3),max(%3) from %1 where %4")
                            .arg(recordTableNamePrefix().append(suffix))
                            .arg(machSection).arg(heightSection)
                            .arg(sCondition));
        if (!result) {
            d->db.rollback();
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }

        // 读取数据
        if (query.next()) {
            QRectF tempRect;
            tempRect.setLeft(query.value(0).toReal());
            tempRect.setRight(query.value(1).toReal());
            tempRect.setTop(query.value(2).toReal());
            tempRect.setBottom(query.value(3).toReal());
            newRanges.append(tempRect);
        }
    }

    //
    d->db.commit();

    // 检测有效性
    if (newRanges.isEmpty()) {
        //
        qWarning() << QStringLiteral("没有获取到有效范围值");
        return false;
    }

    // 合并区域，取交集
    range = newRanges.takeFirst(); //
    QListIterator<QRectF> citerNewRanges(newRanges);
    while (citerNewRanges.hasNext()) {
        const QRectF &newRange = citerNewRanges.next();
        range = range.intersected(newRange);
    }

    return true;
}

bool JSqlDataMgr::readHotSpotData(const QString &tableName, QList<QRectF> &ranges)
{
    //
    ranges.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = query.exec(QString("SELECT XMIN,XMAX,YMIN,YMAX FROM %1").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    while (query.next()) {
        ranges.append(QRectF(QPointF(query.value(0).toDouble(), query.value(2).toDouble()),
                             QPointF(query.value(1).toDouble(), query.value(3).toDouble())));
    }

    return true;
}

bool JSqlDataMgr::symbolOfName(const JFileNameInfo &info, const QString &name, QString &symbol, bool sift)
{
    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    //
    QString sQuery;
    if (sift) {
        sQuery = QString("select YXHM from %1 where BM='%2' and SXBZ=1 order by oid");
    } else {
        sQuery = QString("select YXHM from %1 where BM='%2' order by oid");
    }

    //
    bool result = query.exec(sQuery
                             .arg(d->tableMgr->generateSignalTableName(info))
                             .arg(name));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (!query.next()) {
        return false;
    }

    //
    symbol = query.value(0).toString();

    return true;
}

bool JSqlDataMgr::clearBaseLine()
{
    Q_D(JSqlDataMgr);
    return d->tableMgr->clearTable(JSqlTableMgr::baseLineTableName());
}

bool JSqlDataMgr::addBaseLine(const QList<QVector<QPointF> > &groupsData)
{
    Q_D(JSqlDataMgr);

    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //JPreciTimer ptimer;
    //ptimer.reset();

    QSqlQuery query(d->db);

    //
    d->db.transaction();

    //
    if (!query.prepare(QString("insert into %1(GROUPID,X,Y) values(?,?,?)")
                       .arg(JSqlTableMgr::baseLineTableName()))) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    //
    int count = groupsData.count();
    for (int i = 0; i < count; ++i) {
        QVectorIterator<QPointF> citerGroupData(groupsData.at(i));
        while (citerGroupData.hasNext()) {
            const QPointF &point = citerGroupData.next();
            query.bindValue(0, i);
            query.bindValue(1, point.x());
            query.bindValue(2, point.y());
            if (!query.exec()) {
                d->db.rollback();
                qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
                continue;
            }
        }
    }

    //
    if (!d->db.commit()) {
        d->db.rollback();
        return false;
    }

    //qDebug() << ptimer.ustick();

    return true;
}

bool JSqlDataMgr::readBaseLine(QList<QVector<QPointF> > &groupsData)
{
    //
    groupsData.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = false;

    // 查询GROUPID
    result = query.exec(QString("select GROUPID from %1 group by GROUPID")
                        .arg(JSqlTableMgr::baseLineTableName()));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    QVector<int> groupIds;
    while (query.next()) {
        groupIds.append(query.value(0).toInt());
    }

    // 查询数据
    QVectorIterator<int> citerGroupIds(groupIds);
    while (citerGroupIds.hasNext()) {
        bool result = query.exec(QString("select X,Y from %1 where GROUPID=%2 order by oid")
                                 .arg(JSqlTableMgr::baseLineTableName())
                                 .arg(citerGroupIds.next()));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            return false;
        }
        // 读取数据
        QVector<QPointF> points;
        while (query.next()) {
            points.append(QPointF(query.value(0).toDouble(),
                                  query.value(1).toDouble()));
        }
        groupsData.append(points);
    }

    return true;
}

bool JSqlDataMgr::readSignalAxisSection(const JFileNameInfo &info,
                                        const QString &axisXName,
                                        const QString &axisYName,
                                        QString &axisXSection,
                                        QString &axisYSection,
                                        bool sift) const
{
    //
    axisXSection.clear();
    axisYSection.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    //
    QString sQuery;
    if (sift) {
        sQuery = QString("select YXHM from %1 where BM='%2' and SXBZ=1 order by oid");
    } else {
        sQuery = QString("select YXHM from %1 where BM='%2' order by oid");
    }

    //
    bool result = query.exec(sQuery
                             .arg(d->tableMgr->generateSignalTableName(info))
                             .arg(axisXName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisXSection = query.value(0).toString();
    }

    // 查询数据
    result = query.exec(sQuery
                        .arg(d->tableMgr->generateSignalTableName(info))
                        .arg(axisYName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisYSection = query.value(0).toString();
    }

    //
    if (axisXSection.isEmpty() || axisYSection.isEmpty()) {
        return false;
    }

    return true;
}

bool JSqlDataMgr::readSignalAxisSection(const QString &tableName,
                                        const QString &axisXName,
                                        const QString &axisYName,
                                        QString &axisXSection,
                                        QString &axisYSection,
                                        bool sift) const
{
    //
    axisXSection.clear();
    axisYSection.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    //
    QString sQuery;
    if (sift) {
        sQuery = QString("select YXHM from %1 where BM='%2' and SXBZ=1 order by oid");
    } else {
        sQuery = QString("select YXHM from %1 where BM='%2' order by oid");
    }

    //
    bool result = query.exec(sQuery.arg(tableName).arg(axisXName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisXSection = query.value(0).toString();
    }

    // 查询数据
    result = query.exec(sQuery.arg(tableName).arg(axisYName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisYSection = query.value(0).toString();
    }

    //
    if (axisXSection.isEmpty() || axisYSection.isEmpty()) {
        return false;
    }

    return true;
}

bool JSqlDataMgr::readSignalAxisName(const JFileNameInfo &info,
                                     const QString &axisXSection,
                                     const QString &axisYSection,
                                     QString &axisXName,
                                     QString &axisYName,
                                     bool sift) const
{
    //
    axisXName.clear();
    axisYName.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    //
    QString sQuery;
    if (sift) {
        sQuery = QString("select BM from %1 where YXHM='%2' and SXBZ=1 order by oid");
    } else {
        sQuery = QString("select BM from %1 where YXHM='%2' order by oid");
    }

    //
    bool result = query.exec(sQuery
                             .arg(d->tableMgr->generateSignalTableName(info))
                             .arg(axisXSection));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisXName = query.value(0).toString();
    }

    // 查询数据
    result = query.exec(QString("select BM from %1 where BM='%2'")
                        .arg(d->tableMgr->generateSignalTableName(info))
                        .arg(axisYSection));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisYName = query.value(0).toString();
    }

    //X
    if (axisXName.isEmpty() || axisYName.isEmpty()) {
        return false;
    }

    return true;
}

bool JSqlDataMgr::readSignalAxisName(const QString &tableName,
                                     const QString &axisXSection,
                                     const QString &axisYSection,
                                     QString &axisXName,
                                     QString &axisYName,
                                     bool sift) const
{
    //
    axisXName.clear();
    axisYName.clear();

    Q_D(const JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    //
    QString sQuery;
    if (sift) {
        sQuery = QString("select BM from %1 where YXHM='%2' and SXBZ=1 order by oid");
    } else {
        sQuery = QString("select BM from %1 where YXHM='%2' order by oid");
    }

    //
    bool result = query.exec(sQuery.arg(tableName).arg(axisXSection));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisXName = query.value(0).toString();
    }

    // 查询数据
    result = query.exec(QString("select BM from %1 where BM='%2'")
                        .arg(tableName).arg(axisYSection));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    // 读取数据
    if (query.next()) {
        axisYName = query.value(0).toString();
    }

    //X
    if (axisXName.isEmpty() || axisYName.isEmpty()) {
        return false;
    }

    return true;
}

bool JSqlDataMgr::deleteAllRecordData(const JFileNameInfo &info)
{
    //
    transaction();

    // 检测是否存在表
    QString DYXHB = JSqlTableMgr::generateSignalTableName(info);
    if (JSqlDataMgr::instance()->existsTable(DYXHB)) {
        // 删除表
        if (!JSqlTableMgr::instance()->deleteTable(DYXHB)) {
            rollback();
            qCritical() << QStringLiteral("删除表[%1]失败！").arg(DYXHB);
            return false;
        }
    }

    // 检测是否存在表
    QString DYZB = JSqlTableMgr::generateRecordTableName(info);
    if (JSqlDataMgr::instance()->existsTable(DYZB)) {
        // 删除表
        if (!JSqlTableMgr::instance()->deleteTable(DYZB)) {
            rollback();
            qCritical() << QStringLiteral("删除表[%1]失败！").arg(DYZB);
            return false;
        }
    }

    // 删除主表信息
    if (!removeMainTableData(info)) {
        rollback();
        qCritical() << QStringLiteral("删除主表信息[%1]失败！").arg(info.toString());
        return false;
    }

    //
    commit();

    return true;
}

bool JSqlDataMgr::deleteRecordData(const QString &tableName,
                                   const QString &symbolTime,
                                   const QTime &minimum,
                                   const QTime &maximum,
                                   bool retain)
{
    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);

    //
    QString sQuery;
    if (retain) {
        sQuery = QString("delete from %1 where %2<'%3' or %2>'%4'");
    } else {
        sQuery = QString("delete from %1 where %2 between '%3' and '%4'");
    }

    //
    bool result = query.exec(sQuery.arg(tableName).arg(symbolTime)
                             .arg(minimum.toString("hh:mm:ss:zzz"))
                             .arg(maximum.toString("hh:mm:ss:zzz")));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }
#if 1
    //
    result = query.exec(QString("vacuum %1;").arg(tableName));
    if (!result) {
        return false;
    }
#endif
    return true;
}

bool JSqlDataMgr::conherenceRecordTable(const QString &tableName)
{
    Q_D(JSqlDataMgr);

    // 获取表字段名
    QStringList columnNames = JSqlTableMgr::instance()->tableColumns(tableName);
    if (columnNames.count() < 2) {
        return false;
    }

    //
    QString sectionTime = columnNames.at(1);
    QStringList symbols = columnNames.mid(2);

    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    bool result = false;

    //
    d->db.transaction();

    // 1.填充空值
    QStringListIterator citerSymbols(symbols);
    while (citerSymbols.hasNext()) {
        const QString &symbol = citerSymbols.next();
        //
        result = query.exec(QString("update %1 set %3="
                                    "(select min(%3) from %1 where %2 is not null)"
                                    " where %3 is null")
                            .arg(tableName).arg(sectionTime).arg(symbol));
        if (!result) {
            d->db.rollback();
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            continue;
        }
    }

    // 2.创建临时表
    result = query.exec(QString("CREATE TABLE %1_TEMP AS SELECT * FROM %1 GROUP BY %2 ORDER BY %2")
                        .arg(tableName).arg(sectionTime));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }
    // 3.删除旧表
    result = query.exec(QString("DROP TABLE %1").arg(tableName));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }
    // 4.更改表名
    result = query.exec(QString("ALTER TABLE %1_TEMP RENAME TO %1").arg(tableName));
    if (!result) {
        d->db.rollback();
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    //
    d->db.commit();

    return true;
}

void *JSqlDataMgr::database()
{
    Q_D(JSqlDataMgr);
    return (void *)&d->db;
}

bool JSqlDataMgr::removeRecordByJC(const QList<int> &jcs)
{
    //
    if (jcs.isEmpty()) {
        return true;
    }

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    // 查询数据
    QSqlQuery query(d->db);
    query.setForwardOnly(true);

    QString conditions;
    QListIterator<int> citerJCs(jcs);
    while (citerJCs.hasNext()) {
        conditions.append(QString::number(citerJCs.next()) + ",");
    }
    conditions.chop(1);

    // 获取信号表、值表名称
    QStringList suffixes;
    bool result = query.exec(QString("select DYXHB from %1"
                                     " where JC in(%2)")
                             .arg(d->tableMgr->mainTableName())
                             .arg(conditions));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    while (query.next()) {
        suffixes.append(query.value(0).toString().section('_', 2));
    }

    //
    if (suffixes.isEmpty()) {
        return true;
    }

    // 从主表删除JC相关项
    result = query.exec(QString("delete from %1"
                                " where JC in(%2)")
                        .arg(d->tableMgr->mainTableName())
                        .arg(conditions));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        return false;
    }

    //
    QString tableName;
    QStringListIterator citerSuffixes(suffixes);
    while (citerSuffixes.hasNext()) {
        const QString &suffix = citerSuffixes.next();
        // 从主表删除
        tableName = d->tableMgr->signalTableNamePrefix().append(suffix);
        result = query.exec(QString("delete from %1 where DYXHB='%2'")
                            .arg(d->tableMgr->mainTableName())
                            .arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //return false;
        }
        // 信号表
        tableName = d->tableMgr->signalTableNamePrefix().append(suffix);
        result = query.exec(QString("drop table %1").arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //continue;
        }
        //
        result = query.exec(QString("vacuum %1;").arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //return false;
        }
        // 值表
        tableName = d->tableMgr->recordTableNamePrefix().append(suffix);
        result = query.exec(QString("drop table %1").arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //continue;
        }
        //
        result = query.exec(QString("vacuum %1;").arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //return false;
        }
        // 热点范围表
        tableName = d->tableMgr->hotSpotTableNamePrefix().append(suffix);
        result = query.exec(QString("drop table %1").arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //continue;
        }
        //
        result = query.exec(QString("vacuum %1;").arg(tableName));
        if (!result) {
            qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
            //return false;
        }
    }

    return true;
}

bool JSqlDataMgr::removeTables(const QString &suffix)
{
    //
    if (suffix.isEmpty()) {
        return true;
    }

    Q_D(JSqlDataMgr);
    if (!d->db.isOpen()) {
        qCritical() << QStringLiteral("数据库未打开！");
        return false;
    }

    //
    QSqlQuery query(d->db);
    query.setForwardOnly(true);
    QString tableName;
    bool result = true;

    // 从主表删除
    tableName = d->tableMgr->signalTableNamePrefix().append(suffix);
    result = query.exec(QString("delete from %1 where DYXHB='%2'")
                        .arg(d->tableMgr->mainTableName())
                        .arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }

    // 信号表
    tableName = d->tableMgr->signalTableNamePrefix().append(suffix);
    result = query.exec(QString("drop table %1").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }
    //
    result = query.exec(QString("vacuum %1;").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }
    // 值表
    tableName = d->tableMgr->recordTableNamePrefix().append(suffix);
    result = query.exec(QString("drop table %1").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }
    //
    result = query.exec(QString("vacuum %1;").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }
    // 热点范围表
    tableName = d->tableMgr->hotSpotTableNamePrefix().append(suffix);
    result = query.exec(QString("drop table %1").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }
    //
    result = query.exec(QString("vacuum %1;").arg(tableName));
    if (!result) {
        qCritical() << QStringLiteral("命令执行失败！[%1]").arg(query.lastError().text());
        //return false;
    }

    return true;
}

JSqlDataMgr::JSqlDataMgr() :
    d_ptr(new JSqlDataMgrPrivate(this))
{
    Q_D(JSqlDataMgr);
    d->tableMgr = JSqlTableMgr::instance();
    Q_ASSERT(d->tableMgr->isValid());
    if (d->tableMgr->isValid()) {
        d->db = QSqlDatabase::database(d->tableMgr->connectionName());
        d->query = QSqlQuery(d->db);
    } else {
        qCritical() << QStringLiteral("JSqlTableMgr必须在初始化JSqlDataMgr之前加载配置文件！");
    }
}

JSqlDataMgr::~JSqlDataMgr()
{
    delete d_ptr;
}

